package top.lyjwn.todo.security.impl;

import com.alibaba.fastjson2.JSONObject;
import org.noear.solon.annotation.Component;
import org.noear.solon.annotation.Inject;
import org.noear.solon.core.handle.Context;
import org.noear.solon.scheduling.annotation.Async;
import top.lyjwn.todo.redis.RedisMap;
import top.lyjwn.todo.security.Login;
import top.lyjwn.todo.security.LoginToken;
import top.lyjwn.todo.sm.SM2KeyPair;
import top.lyjwn.todo.sm.SM2Util;

@Component
public class LoginTokenImpl implements LoginToken {


    @Inject
    private RedisMap redisMap;


    @Inject("${todo.token.expire}")
    private Integer expire = 60 * 60 * 2;

    /**
     * 创建token
     *
     * @param login
     * @return
     */
    public String buildToken(Login login) {
        StringBuffer redisKEY = new StringBuffer("token:");
        SM2KeyPair sm2Key = SM2Util.getSM2Key();
        StringBuffer token = new StringBuffer(sm2Key.getPublicKey());
        redisKEY.append(token);
        login.setPrivateKey(sm2Key.getPrivateKey());
        if (redisMap.set(redisKEY.toString(), JSONObject.toJSONString(login), expire)) {
            return token.toString();
        } else {
            return null;
        }
    }

    /**
     * 延期token
     *
     * @param token
     */
    @Async
    public void postpone(String token) {
        if (token == null) {
            return;
        }
        redisMap.delay("token:" + token, expire);
    }

    /**
     * 刷新用户 token
     *
     * @param login
     */
    public void refreshUserToken(Login login) {
        Context ctx = Context.current();
        if (ctx == null) {
            return;
        }
        String token = ctx.header("token");
        Login loginByToken = getLoginByToken(token);
        redisMap.delete(token);
        redisMap.set("token:" + token, JSONObject.toJSONString(loginByToken));
    }

    /**
     * 用户退出登陆
     *
     * @param token
     */
    public void loginOff(String token) {
        if (token != null) {
            redisMap.delete("token:" + token);
        }
    }

    /**
     * 用户退出登陆
     */
    public void loginOff() {
        Context ctx = Context.current();
        if (ctx == null) {
            return;
        }
        String token = ctx.header("token");
        this.loginOff(token);
    }

    /**
     * 获取登录信息
     *
     * @param token
     * @return loginJson
     */
    public Login getLoginByToken(String token) {
        String str = redisMap.get("token:" + token);
        if (str == null) {
            return null;
        }
        JSONObject jsonObject = JSONObject.parseObject(str);
        if (jsonObject == null) {
            return null;
        }
        return Login.instance(jsonObject);
    }

    /**
     * 获取登录信息
     *
     * @return
     */
    public Login getLogin() {
        Context ctx = Context.current();
        if (ctx == null) {
            return null;
        }
        String token = ctx.header("token");
        if (token == null) {
            return null;
        }
        return getLoginByToken(token);
    }

    /**
     * 验证token
     *
     * @param token
     * @return
     */
    public boolean verify(String token) {
        Login login = getLoginByToken(token);
        String verifyStr = "TODO";
        String privateKey = login.getPrivateKey();
        String encrypt = SM2Util.encrypt(verifyStr, token);
        String decrypt = SM2Util.decrypt(encrypt, privateKey);
        return verifyStr.equals(decrypt);
    }

    /**
     * 身份验证拦截器处理
     *
     * @param token
     * @return
     */
//    public R auth(String token, HttpServletResponse httpServletResponse,
//                                       Object object) {
//        HandlerMethod handlerMethod = (HandlerMethod) object;
//        Method method = handlerMethod.getMethod();
//        // 返回的结果
//        R r = new R();
//        // 检查是否有passtoken注释，有则跳过认证
//        if (method.isAnnotationPresent(ExemptToken.class)) {
//            ExemptToken passToken = method.getAnnotation(ExemptToken.class);
//            if (passToken.required()) {
//                return r.ok("免token请求");
//            }
//        }
//        // 如果没有免除token的请求，则进行验证
//        if (token == null) {
//            return r.error(401, "未发现token");
//        }
//        // 如果用户查找不到，则为假的token
//        if (getLoginByToken(token) == null) {
//            return r.error(401, "查询不到用户信息");
//        }
//        // 验证 token ,加密的正确性
//        if (verify(token)) {
//
//            return r.ok("token验证成功");
//        } else {
//            return r.error(401, "token验证失败");
//        }
//
//    }

}
